package top.gytf.unifiedcall.model.detail;

import cn.hutool.core.lang.Assert;
import lombok.Getter;

import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.lang.String.format;

/**
 * 版本
 */
@Getter
public final class Version {
    private static final Pattern VERSION_PATTERN = Pattern.compile("^(\\d+)\\.(\\d+)\\.(\\d+)$");

    /**
     * 解析版本号
     */
    public static Version valueOf(String version) {
        Assert.notNull(version, "版本号不能为空");
        Matcher matcher = VERSION_PATTERN.matcher(version);
        Assert.isTrue(matcher.matches(), "版本号[ {} ]格式错误", version);
        return new Version(Integer.parseInt(matcher.group(1)), Integer.parseInt(matcher.group(2)), Integer.parseInt(matcher.group(3)));
    }
    public static Version valueOf(int major, int minor, int patch) {
        return new Version(major, minor, patch);
    }

    /**
     * 主版本号，从0开始计数的正整数，当完成里程牌迭代后累加，累加后重置次版本号和修订号
     */
    private final int major;
    /**
     * 次版本号，从0开始计数的正整数，当进行了不兼容的迭代后累加，累加后重置修订号
     */
    private final int minor;
    /**
     * 修订号，从0开始计数的正整数，每次迭代后累加
     */
    private final int patch;

    /**
     * 版本号字符串
     */
    private final String value;

    public Version(int major, int minor, int patch) {
        this.major = major;
        this.minor = minor;
        this.patch = patch;
        this.value =  format("%d.%d.%d", major, minor, patch);
    }

    /**
     * 本版本是否兼容另一个版本
     */
    public boolean isCompatible(Version other) {
        return this.major == other.major && this.minor == other.minor && this.patch >= other.patch;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {return true;}
        if (o == null || getClass() != o.getClass()) {return false;}
        Version that = (Version) o;
        return Objects.equals(getValue(), that.getValue());
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(getValue());
    }

    @Override
    public String toString() {
        return getValue();
    }
}
